package com.ebupt.migu.music.schedule;

import java.io.*;
import java.util.Date;
import java.util.HashMap;
import java.util.Properties;

import javax.annotation.Resource;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.scheduling.annotation.EnableScheduling;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;

import com.ebupt.migu.common.util.DateUtil;
import com.ebupt.migu.music.common.utils.ESearch;
import com.ebupt.migu.music.common.utils.PatternVer;
import com.ebupt.migu.music.userGroup.mapper.NewCrowdMapper;
import com.jcraft.jsch.ChannelSftp;
import com.jcraft.jsch.JSch;
import com.jcraft.jsch.Session;

import lombok.extern.slf4j.Slf4j;

/**
 * @author liuyangyang@e-byte.com
 * @description: TODO
 * @date 2024/11/13 10:54
 */
@Slf4j
@Component
@EnableScheduling
public class IndustryLabelCustomerTask {
    @Value("${industry.ip}")
    private String ip;
    @Value("${industry.port}")
    private int port;
    @Value("${industry.username}")
    private String username;
    @Value("${industry.password}")
    private String password;
    @Value("${industry.remote_dir}")
    private String remote_dir;
    @Value("${industry.local_dir}")
    private String local_dir;

    @Autowired
    private ESearch eSearch;
    @Autowired
    private NewCrowdMapper mapper;
    @Resource
    private RedisTemplate redisTemplate;
    // 定义包含字母和数字的字符数组
    private static final char[] CHARACTERS =
        "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789".toCharArray();

    @Scheduled(initialDelay = 3000, fixedDelay = 1000 * 60)
    public void industry() {
        try {
            // 查询出最先创建的行业标签客群
            HashMap<String, Object> customer = mapper.qryIndustryLabelCustomers();
            if (null == customer || customer.isEmpty()) {
                return;
            }

            String industryLabelCustomerGroupId = String.valueOf(customer.get("industryGroupId"));

            // 生成用户群ID
            Date date = new Date();
            String groupId = (null == customer.get("groupId")
                ? "IN" + DateUtil.parseDateToStr(date, DateUtil.DATE_TIME_FORMAT_YYYYMMDDHHMISS)
                : String.valueOf(customer.get("groupId")));
            log.info("客群ID：{}", groupId);

            // 将状态修改为同步中
            updateCustomerStatus(industryLabelCustomerGroupId, "2", groupId);

            String fileName = String.valueOf(customer.get("fileName"));

            // 从SFTP服务器同步文件
            sftp_download(fileName);

            // redis key
            String uidRedisKey = groupId + "-uid";
            String phoneRedisKey = groupId + "-phone";

            // 删除redis数据
            redisTemplate.delete(uidRedisKey);
            redisTemplate.delete(phoneRedisKey);

            // 下载完成后的本地文件
            String file = local_dir + fileName;
            try (FileReader reader = new FileReader(file); BufferedReader bufferedReader = new BufferedReader(reader)) {
                String line;
                while ((line = bufferedReader.readLine()) != null) {
                    log.info("行数据：{}", line);
                    String[] data = line.split("\\|\\^\\|");
                    String uid = null == data[1] ? "" : data[1];
                    String msisdn = null == data[0] ? "" : data[0];
                    log.info("客群：{}，录入uid：{}", groupId, uid);
                    redisTemplate.opsForSet().add(uidRedisKey, uid);
                    if (PatternVer.isMsisdn(msisdn)) {
                        log.info("客群：{}，录入msisdn：{}", groupId, msisdn);
                        redisTemplate.opsForSet().add(phoneRedisKey, msisdn);
                    }
                }
            }

            // 将状态修改为完成
            updateCustomerStatus(industryLabelCustomerGroupId, "0", groupId);

            // 获取redis中的客群规模
            long clientUser = getSetSizeSafely(uidRedisKey, redisTemplate);
            long mobileUser = getSetSizeSafely(phoneRedisKey, redisTemplate);
            long userGroupSize = clientUser > mobileUser ? clientUser : mobileUser;

            HashMap<String, Object> userGroupInfo = new HashMap<>();
            userGroupInfo.put("groupId", groupId);
            userGroupInfo.put("mobileUser", mobileUser);
            userGroupInfo.put("clientUser", clientUser);
            userGroupInfo.put("userGroupSize", userGroupSize);
            userGroupInfo.put("createStatus", 5);
            userGroupInfo.put("createWay", 3);
            userGroupInfo.put("userGroupName", "行业标签_" + customer.get("userGroupName"));
            userGroupInfo.put("creatorId", customer.get("creatorId"));
            userGroupInfo.put("creatorName", customer.get("creatorName"));
            userGroupInfo.put("creatorDepartment", customer.get("creatorDepartmentName"));
            userGroupInfo.put("creatorPhone", customer.get("creatorPhone"));
            userGroupInfo.put("creatorEmail", customer.get("creatorEmail"));

            // 更新或创建客群信息
            Integer exist = mapper.qryUserGroupInfo(groupId);
            if (null == exist || exist == 0) {
                mapper.createUserGroup(userGroupInfo);
            } else {
                mapper.updateCrowd(userGroupInfo);
            }
        } catch (IOException e) {
            log.error("在处理行业标签客群任务时发生IO异常", e);
        } catch (Exception e) {
            log.error("在处理行业标签客群任务时发生未知异常", e);
        }
    }

    private void updateCustomerStatus(String industryLabelCustomerGroupId, String status, String groupId) {
        HashMap<String, Object> statusMap = new HashMap<>();
        statusMap.put("industryGroupId", industryLabelCustomerGroupId);
        statusMap.put("groupId", groupId);
        statusMap.put("status", status);
        mapper.update(statusMap);
    }

    private long getSetSizeSafely(String key, RedisTemplate redisTemplate) {
        Long size = (Long)redisTemplate.opsForSet().size(key);
        return size == null ? 0 : size;
    }

    /**
     * SFTP下载文件
     *
     * @param fileName
     */
    public void sftp_download(String fileName) {
        JSch jSch = new JSch();
        Session session = null;
        ChannelSftp channelSftp = null;
        try {
            // 创建JSch对象并获取会话
            session = jSch.getSession(username, ip, port);
            session.setPassword(password);
            // 设置连接属性，这里设置为不进行严格的主机密钥检查（生产环境需谨慎考虑）
            Properties config = new Properties();
            config.put("StrictHostKeyChecking", "no");
            session.setConfig(config);
            // 建立连接
            session.connect();
            // 打开SFTP通道
            channelSftp = (ChannelSftp)session.openChannel("sftp");
            channelSftp.connect();
            // 切换到远程目录
            channelSftp.cd(remote_dir);
            // 创建本地文件对象
            File localFile = new File(local_dir + fileName);
            OutputStream outputStream = new FileOutputStream(localFile);
            // 下载文件
            channelSftp.get(fileName, outputStream);
            outputStream.close();
            // 关闭SFTP通道和会话
            channelSftp.disconnect();
            session.disconnect();
        } catch (Exception e) {
            log.error("在SFTP下载文件时发生异常", e);
        } finally {
            if (channelSftp != null && channelSftp.isConnected()) {
                channelSftp.disconnect();
            }
            if (session != null && session.isConnected()) {
                session.disconnect();
            }
        }
    }
}
